﻿using System.Collections.Generic;
using Kiva7.DataClasses;
using System.Collections.ObjectModel;
using System.Linq;
using Kiva7.Translations;

namespace Kiva7.ViewModels
{
    public class LoansViewModel : BaseViewModel
    {
        public LoansViewModel(JournalEntryViewModel journalEntries)
        {
            _JournalEntries = journalEntries;
            CreateCollections();
        }

        private void CreateCollections()
        {
            this._loans = new LoanViewModelCollection(AppResources.Loans);
            this._data = new LoanViewModelCollection(AppResources.Outstanding);

            this._funded = new LoanViewModelCollection(AppResources.Funded);
            this._refunded = new LoanViewModelCollection(AppResources.Refunded);

            this._fundraising = new LoanViewModelCollection(AppResources.Fundraising);
            this._paid = new LoanViewModelCollection(AppResources.Paid);
            this._inRepayment = new LoanViewModelCollection(AppResources.InRepayment);
            this._defaulted = new LoanViewModelCollection(AppResources.Defaulted);
            this._expired = new LoanViewModelCollection(AppResources.Expired);


            this._loansPerSector = new LoanTotalsCollection();
            this._loansPerCountry = new LoanTotalsCollection();
        }

        private JournalEntryViewModel _JournalEntries;

        private List<LoanViewModelCollection> _loansPerType;
        public List<LoanViewModelCollection> LoansPerType
        {
            get
            {
                return _loansPerType;
                
            }
            private set
            {
                if (value != LoansPerType)
                {
                    _loansPerType = value;
                    NotifyPropertyChanged("LoansPerType");
                }
            }
        }

        private LoanTotalsCollection _loansPerCountry;
        public LoanTotalsCollection LoansPerCountry
        {
            get
            {
                return _loansPerCountry;

            }
            private set
            {
                if (value != LoansPerCountry)
                {
                    _loansPerCountry = value;
                    NotifyPropertyChanged("LoansPerCountry");
                }
            }
        }

        private LoanTotalsCollection _loansPerSector;
        public LoanTotalsCollection LoansPerSector
        {
            get
            {
                return _loansPerSector;

            }
            private set
            {
                if (value != LoansPerSector)
                {
                    _loansPerSector = value;
                    NotifyPropertyChanged("LoansPerSector");
                }
            }
        }

        public double RepaidPercentage
        {
            get
            {
                if (_inRepayment.LoanAmount == 0)
                    return 0;

                return (_inRepayment.PaidAmount / _inRepayment.LoanAmount) * 100;

            }
        }


        private LoanViewModelCollection _loans;
        public LoanViewModelCollection Loans
        {
            get
            {
                return _loans;
            }
        }

        private LoanViewModelCollection _data;
        public LoanViewModelCollection Data
        {
            get
            {
                return _data;
            }
        }
        public int OutstandingCount
        {
            get
            {
                return _data.Count;
            }
        }

        private LoanViewModelCollection _fundraising;
        public LoanViewModelCollection Fundraising
        {
            get
            {
                return _fundraising;
            }
        }
        public int FundraisingCount
        {
            get
            {
                return _fundraising.Count;
            }
        }

        private LoanViewModelCollection _funded;
        public LoanViewModelCollection Funded
        {
            get
            {
                return _funded;
            }
        }
        public int FundedCount
        {
            get
            {
                return _funded.Count;
            }
        }

        private LoanViewModelCollection _refunded;
        public LoanViewModelCollection Refunded
        {
            get
            {
                return _refunded;
            }
        }
        public int RefundedCount
        {
            get
            {
                return _refunded.Count;
            }
        }

        private LoanViewModelCollection _inRepayment;
        public LoanViewModelCollection InRepayment
        {
            get
            {
                return _inRepayment;
            }
        }
        public int InRepaymentCount
        {
            get
            {
                return _inRepayment.Count;
            }
        }

        private LoanViewModelCollection _paid;
        public LoanViewModelCollection Paid
        {
            get
            {
                return _paid;
            }
        }
        public int PaidCount
        {
            get
            {
                return _paid.Count;
            }
        }

        private LoanViewModelCollection _defaulted;
        public LoanViewModelCollection Defaulted
        {
            get
            {
                return _defaulted;
            }
        }
        public int DefaultedCount
        {
            get
            {
                return _defaulted.Count;
            }
        }

        private LoanViewModelCollection _expired;
        public LoanViewModelCollection Expired
        {
            get
            {
                return _expired;
            }
        }
        public int ExpiredCount
        {
            get
            {
                return _expired.Count;
            }
        }


        public void SetLoans(LoanList loanItems)
        {
            CountLoansForChart(loanItems);

            foreach (Loan l in loanItems)
            {
                //LoanViewModel l = new LoanViewModel(loan);
                
                Loans.Add(l);

                LoansPerSector.Add(l.Sector, 1);
                if (l.Location != null)
                {
                    LoansPerCountry.Add(l.Location.Country, 1);
                }

                if (l.Status == LoanStatus.InRepayment
                    || l.Status == LoanStatus.Funded
                    || l.Status == LoanStatus.Fundraising)
                {
                    Data.Add(l);
                }
                if (l.Status == LoanStatus.Fundraising)
                {
                    Fundraising.Add(l);
                }

                if (l.Status == LoanStatus.Funded)
                {
                    Funded.Add(l);
                }
                if (l.Status == LoanStatus.Refunded)
                {
                    Refunded.Add(l);
                }

                if (l.Status == LoanStatus.InRepayment)
                {
                    InRepayment.Add(l);
                }
                if (l.Status == LoanStatus.Paid)
                {
                    Paid.Add(l);
                }
                if (l.Status == LoanStatus.Defaulted)
                {
                    Defaulted.Add(l);
                }
                if (l.Status == LoanStatus.Expired)
                {
                    Expired.Add(l);
                }

            }

            List<LoanViewModelCollection> lpt = new List<LoanViewModelCollection>();

            lpt.Add(Funded);
            lpt.Add(Refunded);
            lpt.Add(Fundraising);
            lpt.Add(Paid);
            lpt.Add(InRepayment);
            lpt.Add(Defaulted);
            lpt.Add(Expired);

            LoansPerType = lpt;

            NotifyPropertyChanged("Data");

            NotifyPropertiesChanged();

            _JournalEntries.LoadJournalEntries(loanItems);
        }

        private readonly LoanMonthTotalsDictionary _loansForChart = new LoanMonthTotalsDictionary();

        private void CountLoansForChart(LoanList loanItems)
        {
            foreach (Loan l in loanItems)
            {
                _loansForChart.Add(l);
            }

            LoanMonthTotalsList loansTotals = new LoanMonthTotalsList();
            LoanMonthTotals tempTotals = new LoanMonthTotals();
            foreach (LoanMonthTotals totals in _loansForChart.Values.Reverse())
            {
                tempTotals.Addition(totals);
                loansTotals.Add(new LoanMonthTotals(tempTotals));
            }

            LoansTotals = loansTotals;
        }

        private LoanMonthTotalsList _loansTotals;
        public LoanMonthTotalsList LoansTotals
        {
            get
            {
                return _loansTotals;

            }
            private set
            {
                if (value != _loansTotals)
                {
                    _loansTotals = value;
                    NotifyPropertyChanged("LoansTotals");
                }
            }
        }

        internal void Clear()
        {
            _JournalEntries.Clear();
            _loansForChart.Clear();

            if (LoansPerType != null)
            {
                foreach (var l in LoansPerType)
                {
                    l.Clear();
                }
            }
            CreateCollections();

            NotifyPropertyChanged("Loans");

            NotifyPropertiesChanged();

            NotifyPropertyChanged("LoansTotals");

        }

        private void NotifyPropertiesChanged()
        {
            NotifyPropertyChanged("FundraisingCount");
            NotifyPropertyChanged("FundedCount");
            NotifyPropertyChanged("RefundedCount");
            NotifyPropertyChanged("InRepaymentCount");
            NotifyPropertyChanged("PaidCount");
            NotifyPropertyChanged("DefaultedCount");
            NotifyPropertyChanged("ExpiredCount");
            NotifyPropertyChanged("RepaidPercentage");
        }
    }
}
